package com.lizhi.note.service.impl;


import com.lizhi.note.dto.AppUserDTO;
import com.lizhi.note.entity.AppUserEntity;
import com.lizhi.note.mapper.AppUserMapper;
import com.lizhi.note.repository.AppUserRepository;
import com.lizhi.note.service.AppUserService;
import com.mysql.cj.exceptions.PasswordExpiredException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;

@Service
@Transactional
public class AppUserServiceImpl implements AppUserService {

    private final AppUserRepository userRepository;
    private final AppUserMapper userMapper;
    private final PasswordEncoder passwordEncoder;
    public AppUserServiceImpl(AppUserRepository userRepository, AppUserMapper userMapper, PasswordEncoder passwordEncoder) {
        this.userRepository = userRepository;
        this.userMapper = userMapper;
        this.passwordEncoder = passwordEncoder;
    }

    // 创建用户（加密密码）
    @Override
    public AppUserDTO createUser(AppUserDTO userDto) {

        // 验证唯一性
        validateUniqueFields(userDto);

        AppUserEntity entity = userMapper.toEntity(userDto);

        // 加密密码
        entity.setPassword(passwordEncoder.encode(userDto.getPassword()));

        AppUserEntity savedEntity = userRepository.save(entity);

        return userMapper.toDto(savedEntity);
    }

    @Override
    public Optional<AppUserDTO> getUserById(Long id) {
        return userRepository.findById(id)
                .map(userMapper::toDto);
    }

    @Override
    public Optional<AppUserDTO> getUserByUsername(String username) {
        return userRepository.findByUsername(username)
                .map(userMapper::toDto);
    }

    @Override
    public Page<AppUserDTO> getAllUsers(Pageable pageable) {
        return userRepository.findAll(pageable)
                .map(userMapper::toDto);
    }

    @Override
    public List<AppUserDTO> getAllUsers() {
        List<AppUserEntity> entities = userRepository.findAll();
        return userMapper.toDtoList(entities);
    }

    @Override
    public AppUserDTO updateUser(Long id, AppUserDTO userDto) {
        AppUserEntity entity = userRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("用户不存在"));

        // 验证唯一性（排除当前用户）
        validateUniqueFieldsExcludingCurrent(userDto, entity);

        // 更新非敏感字段
        entity.setUsername(userDto.getUsername());
        entity.setPhone(userDto.getPhone());
        entity.setEmail(userDto.getEmail());
        entity.setActiveName(userDto.getActiveName());
        AppUserEntity updatedEntity = userRepository.save(entity);
        return userMapper.toDto(updatedEntity);
    }

    @Override
    public void deleteUser(Long id) {
        userRepository.deleteById(id);
    }

    @Override
    public boolean existsByUsername(String username) {
        return userRepository.existsByUsername(username);
    }

    @Override
    public boolean existsByPhone(String phone) {
        return userRepository.existsByPhone(phone);
    }

    @Override
    public void updatePassword(Long id, String oldPassword, String newPassword) {
        AppUserEntity entity = userRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("用户不存在"));

        // 验证旧密码
        if (!passwordEncoder.matches(oldPassword, entity.getPassword())) {
            throw new PasswordExpiredException("旧密码不正确");
        }

        // 设置新密码（加密）
        entity.setPassword(passwordEncoder.encode(newPassword));
        userRepository.save(entity);
    }

    // 辅助方法：验证字段唯一性
    private void validateUniqueFields(AppUserDTO userDTO) {
        if (userRepository.existsByUsername(userDTO.getUsername())) {
            throw new RuntimeException("用户名已存在");
        }
        if (userRepository.existsByPhone(userDTO.getPhone())) {
            throw new RuntimeException("手机号已存在");
        }
        if (userRepository.existsByEmail(userDTO.getEmail())) {
            throw new RuntimeException("邮箱已存在");
        }
    }

    // 辅助方法：验证字段唯一性（排除当前用户）
    private void validateUniqueFieldsExcludingCurrent(AppUserDTO userDTO, AppUserEntity currentUser) {
        if (!currentUser.getUsername().equals(userDTO.getUsername()) &&
                userRepository.existsByUsername(userDTO.getUsername())) {
            throw new RuntimeException("用户名已存在");
        }
        if (!currentUser.getPhone().equals(userDTO.getPhone()) &&
                userRepository.existsByPhone(userDTO.getPhone())) {
            throw new RuntimeException("手机号已存在");
        }
        if (!currentUser.getEmail().equals(userDTO.getEmail()) &&
                userRepository.existsByEmail(userDTO.getEmail())) {
            throw new RuntimeException("邮箱已存在");
        }
    }
}
